<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>框选元素</title>
  <style>
      * {
          margin: 0;
          padding: 0;
          user-select: none;
      }
      #box1 {
          position: absolute;
          left: 10px;
          top: 10px;
          width: 100px;
          height: 100px;
          background: yellow;
      }

      #box2 {
          position: absolute;
          left: 200px;
          top: 200px;
          width: 200px;
          height: 200px;
          background: red;
      }
  </style>
</head>
<body>
<!--
题目：实现鼠标框选两个 div

思路：
1. 通过鼠标的点击、移动、放开事件实现
2. 点击的时候生成一个div
3. 然后鼠标移动事件的时候获取移动的坐标及宽高赋值给div
4. 放开事件，先清空selectBox，让鼠标移动事件停止执行
5. 获取到界面中所有的div，然后去遍历通过getBoundingClientRect获取到每个div的x,y坐标
6. 判断框选的坐标是否包含选中元素的起始x,y和结束x,y
-->
  <div id="box1">1</div>
  <div id="box2">2</div>
</body>
<script>
  // 鼠标按下和放开的x，y轴
  let startX = 0
  let startY = 0
  let selectBox = null

  // 鼠标按下事件的处理
  document.addEventListener("mousedown", event => {
    const { clientX, clientY } = event
    startX = clientX
    startY = clientY

    // 情况已存在的框
    if (document.querySelector("#rectangle")) {
      const ele = document.querySelector("#rectangle")
      ele.remove()
    }

    // 创建一个div，作为框选的框
    selectBox = document.createElement("div")
    selectBox.id = "rectangle"
    document.body.appendChild(selectBox)
  });

  // 鼠标移动，计算出框选元素的宽高
  document.addEventListener("mousemove", event => {
    if (selectBox) {
      const { clientX, clientY } = event
      selectBox.style.position = "absolute"
      // 用Math.min去获取最小的位置，用于从下往上框选的情况
      selectBox.style.top = `${Math.min(startY, clientY)}px`
      selectBox.style.left = `${Math.min(startX, clientX)}px`
      selectBox.style.width = `${Math.abs(clientX - startX)}px`
      selectBox.style.height = `${Math.abs(clientY - startY)}px`
      selectBox.style.border = "1px dotted #000"
    }
  });

  // 鼠标放开事件的处理
  document.addEventListener("mouseup", () => {
    // 把selectBox设置为null，为了关闭鼠标移动事件
    selectBox = null
    // 获取所有的div
    const divList = document.querySelectorAll("div")
    // 获取生成的矩形框，在调用getBoundingClientRect方法，拿到他的x,y,right,bottom属性
    const rectangle = document.querySelector("#rectangle").getBoundingClientRect()
    // 用于接受结果
    const result = []
    if (divList.length) {
      // 循环所有的div，判断他的起始坐标x，y和结束坐标x，y是否在框选范围内
      divList.forEach(v => {
        const itemBox = v.getBoundingClientRect()
        if (
          // 过滤掉生成的框选框
          v.id !== 'rectangle' &&
          // 判断开始的x，y坐标
          itemBox.x >= rectangle.x &&
          itemBox.y >= rectangle.y &&
          // 判断结束的x，y坐标
          itemBox.bottom <= rectangle.bottom &&
          itemBox.right <= rectangle.right
        ) result.push(v)
      })
    }
    console.log(result, 'newArr')
  });
</script>
</html>
